home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 198_02 / vmsvt.c < prev    next >
C/C++ Source or Header  |  1990-01-21  |  13KB  |  601 lines

  1. /*
  2.  *  Advanced VMS terminal driver
  3.  *
  4.  *  Knows about any terminal defined in SMGTERMS.TXT and TERMTABLE.TXT
  5.  *  located in SYS$SYSTEM.
  6.  *
  7.  *  Author:  Curtis Smith
  8.  *  Last Updated: 07/14/87
  9.  */
  10.  
  11. #include    <stdio.h>        /* Standard I/O package        */
  12. #include    "estruct.h"        /* Emacs' structures        */
  13. #include    "edef.h"        /* Emacs' definitions        */
  14.  
  15. #if    VMSVT
  16.  
  17. #include     <descrip.h>        /* Descriptor definitions    */
  18.  
  19. /*  These would normally come from iodef.h and ttdef.h  */
  20. #define IO$_SENSEMODE    0x27        /* Sense mode of terminal    */
  21.  
  22. #include    <ttdef.h>
  23.  
  24. /* #define TT$_UNKNOWN    0x00 */        /* Unknown terminal        */
  25.  
  26. /** Forward references **/
  27. int vmsopen(), vmsclose(), vmskopen(), vmskclose(), ttgetc(), ttputc();
  28. int ttflush(), vmsmove(), vmseeol(), vmseeop(), vmsbeep(), vmsrev();
  29. int vmscres();
  30. extern int eolexist, revexist;
  31. extern char sres[];
  32.  
  33. #define    ESC    27
  34.  
  35. #if COLOR
  36. int vmsfcol(), vmsbcol();
  37.  
  38. int isansi = 0;        /* has support for ansi color */
  39. int cfcolor = -1;    /* current forground color */
  40. int cbcolor = -1;    /* current background color */
  41. int usedcolor = 0;    /* true if used a color */
  42. #endif
  43.  
  44. /** SMG stuff **/
  45. static char * begin_reverse, * end_reverse, * erase_to_end_line;
  46. static char * erase_whole_display;
  47. static int termtype;
  48. static int vmstermtype;
  49.  
  50. #define SMG$K_BEGIN_REVERSE        0x1bf
  51. #define SMG$K_END_REVERSE        0x1d6
  52. #define SMG$K_SET_CURSOR_ABS        0x23a
  53. #define SMG$K_ERASE_WHOLE_DISPLAY    0x1da
  54. #define SMG$K_ERASE_TO_END_LINE        0x1d9
  55.  
  56.  
  57. /* Dispatch table. All hard fields just point into the terminal I/O code. */
  58. TERM    term    = {
  59.     24 - 1,                /* Max number of rows allowable */
  60.     /* Filled in */ - 1,        /* Current number of rows used    */
  61.     132,                /* Max number of columns    */
  62.     /* Filled in */ 0,        /* Current number of columns    */
  63.     64,                /* Min margin for extended lines*/
  64.     8,                /* Size of scroll region    */
  65.     100,                /* # times thru update to pause */
  66.     vmsopen,            /* Open terminal at the start    */
  67.     vmsclose,            /* Close terminal at end    */
  68.     vmskopen,            /* Open keyboard        */
  69.     vmskclose,            /* Close keyboard        */
  70.     ttgetc,                /* Get character from keyboard    */
  71.     ttputc,                /* Put character to display    */
  72.     ttflush,            /* Flush output buffers        */
  73.     vmsmove,            /* Move cursor, origin 0    */
  74.     vmseeol,            /* Erase to end of line        */
  75.     vmseeop,            /* Erase to end of page        */
  76.     vmsbeep,            /* Beep                */
  77.     vmsrev,                /* Set reverse video state    */
  78.     vmscres                /* Change screen resolution    */
  79. #if    COLOR
  80.     , vmsfcol,            /* Set forground color        */
  81.     vmsbcol                /* Set background color        */
  82. #endif
  83. };
  84.  
  85. int oldwidth;
  86. int vmsinrev;
  87.  
  88. extern char obuf[NOBUF];    /* output buffer */
  89. extern int nobuf;        /* # of bytes in obuf */
  90.  
  91. #define fastputc(c)    {if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = c;}
  92.  
  93. /***
  94.  *  ttputs  -  Send a string to ttputc
  95.  *
  96.  *  Nothing returned
  97.  ***/
  98. ttputs(string)
  99. char * string;                /* String to write        */
  100. {
  101.     if (string)
  102.         while (*string != '\0')
  103.             fastputc(*string++);
  104. }
  105.  
  106. /***
  107.  * ttputi - Send an integer to ttputc
  108.  ***/
  109. ttputi(i)
  110. int i;
  111. {
  112.     char buf[20];
  113.     int len;
  114.  
  115.     if (i < 0) {ttputc('-'); i = -i;}
  116.     len = 0;
  117.     do {
  118.         buf[len++] = '0' + i % 10;
  119.         i /= 10;
  120.     } while (i > 0);
  121.  
  122.     while (len-- > 0)
  123.         fastputc(buf[len]);
  124. }
  125.  
  126. /***
  127.  *  vmsmove  -  Move the cursor (0 origin)
  128.  *
  129.  *  Nothing returned
  130.  ***/
  131. vmsmove(row, col)
  132. int row;                /* Row position            */
  133. int col;                /* Column position        */
  134. {
  135.     char buffer[32];
  136.     int ret_length;
  137.     static int request_code = SMG$K_SET_CURSOR_ABS;
  138.     static int max_buffer_length = sizeof(buffer);
  139.     static int arg_list[3] = { 2 };
  140.     register char * cp;
  141.  
  142.     register int i;
  143.  
  144.     if (row == phrow+1 && col == 0 && row != scrlbot) {
  145.         fastputc(13); fastputc(10);
  146.     }
  147.  
  148.     else if (vmstermtype == TT$_UNKNOWN) {
  149.         fastputc('\033');    fastputc('=');
  150.         fastputc(row+' ');    fastputc(col+' ');
  151.     }
  152.  
  153.     else {
  154.  
  155.         /* Set the arguments into the arg_list array
  156.          * SMG assumes the row/column positions are 1 based (boo!)
  157.          */
  158.         arg_list[1] = row + 1;
  159.         arg_list[2] = col + 1;
  160.  
  161.         if ((smg$get_term_data(        /* Get terminal data    */
  162.             &termtype,        /* Terminal table address */
  163.             &request_code,        /* Request code        */
  164.             &max_buffer_length,    /* Maximum buffer length */
  165.             &ret_length,        /* Return length    */
  166.             buffer,            /* Capability data buffer */
  167.             arg_list)        /* Argument list array    */
  168.  
  169.         /* We'll know soon enough if this doesn't work        */
  170.                 & 1) == 0) {
  171.                     ttputs("OOPS");
  172.                     return;
  173.                 }
  174.  
  175.         /* Send out resulting sequence                */
  176.         i = ret_length;
  177.         cp = buffer;
  178.         while (i-- > 0)
  179.             fastputc(*cp++);
  180.     }
  181.     phrow = row;
  182. }
  183.  
  184.  
  185. /***
  186.  *  vmsrev  -  Set the reverse video status
  187.  *
  188.  *  Nothing returned
  189.  ***/
  190. vmsrev(status)
  191. int status;                /* TRUE if setting reverse    */
  192. {
  193. #if    COLOR
  194.     if (usedcolor) return;
  195. #endif
  196.     if (vmsinrev == status) return;
  197.     vmsinrev = status;
  198.     if (status)
  199.         ttputs(begin_reverse);
  200.     else 
  201.         ttputs(end_reverse);
  202. }
  203.  
  204. /***
  205.  *  vmscres  -  Change screen resolution (which it doesn't)
  206.  *
  207.  *  Nothing returned
  208.  ***/
  209. vmscres()
  210. {
  211.     /* But it could.  For vt100/vt200s, one could switch from
  212.     80 and 132 columns modes */
  213. }
  214.  
  215.  
  216. #if    COLOR
  217. vmsparm(n)
  218. register int n;
  219. {
  220.     register q,r;
  221.  
  222.     q = n/10;
  223.     if (q != 0)    {
  224.         r = q/10;
  225.         if (r != 0)    {fastputc('0' + r%10);}
  226.         fastputc('0' + q%10);
  227.     }
  228.     fastputc('0' + n%10);
  229. }
  230.  
  231. /***
  232.  *  vmsfcol  -  Set the forground color
  233.  *
  234.  *  Nothing returned
  235.  ***/
  236. vmsfcol(color)
  237. int color;
  238. {
  239.     if (!usedcolor || color == cfcolor)    return;
  240.     fastputc(ESC);
  241.     fastputc('[');
  242.     vmsparm(color + 30);
  243.     fastputc('m');
  244.     cfcolor = color;
  245. }
  246.  
  247. /***
  248.  *  vmsbcol  -  Set the background color
  249.  *
  250.  *  Nothing returned
  251.  ***/
  252. vmsbcol(color)
  253. int color;
  254. {
  255.     if (!usedcolor || color == cbcolor)    return;
  256.     fastputc(ESC);
  257.     fastputc('[');
  258.     vmsparm(color + 40);
  259.     fastputc('m');
  260.     cbcolor = color;
  261. }
  262. #endif
  263.  
  264. /***
  265.  *  vmseeol  -  Erase to end of line
  266.  *
  267.  *  Nothing returned
  268.  ***/
  269. vmseeol()
  270. {
  271. #if    COLOR
  272.     vmsfcol(gfcolor);
  273.     vmsbcol(gbcolor);
  274. #endif
  275.     ttputs(erase_to_end_line);
  276. }
  277.  
  278.  
  279. /***
  280.  *  vmseeop  -  Erase to end of page (clear screen)
  281.  *
  282.  *  Nothing returned
  283.  ***/
  284. vmseeop()
  285. {
  286. #if    COLOR
  287.     vmsfcol(gfcolor);
  288.     vmsbcol(gbcolor);
  289. #endif
  290.     ttputs(erase_whole_display);
  291.     phrow = 1000;
  292. }
  293.  
  294.  
  295. /***
  296.  *  vmsbeep  -  Ring the bell
  297.  *
  298.  *  Nothing returned
  299.  ***/
  300. vmsbeep()
  301. {
  302.     fastputc('\007');
  303. }
  304.  
  305.  
  306. /***
  307.  *  vmsgetstr  -  Get an SMG string capability by name
  308.  *
  309.  *  Returns:    Escape sequence
  310.  *        NULL    No escape sequence available
  311.  ***/ 
  312. char * vmsgetstr(request_code)
  313. int request_code;            /* Request code            */
  314. {
  315.     register char * result;
  316.     static char seq_storage[1024];
  317.     static char * buffer = seq_storage;
  318.     static int arg_list[2] = { 1, 1 };
  319.     int max_buffer_length, ret_length;
  320.  
  321.     /*  Precompute buffer length */
  322.     
  323.     max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
  324.  
  325.     /* Get terminal commands sequence from master table */
  326.  
  327.     if ((smg$get_term_data(    /* Get terminal data        */
  328.         &termtype,    /* Terminal table address    */
  329.         &request_code,    /* Request code            */
  330.         &max_buffer_length,/* Maximum buffer length    */
  331.         &ret_length,    /* Return length        */
  332.         buffer,        /* Capability data buffer    */
  333.         arg_list)    /* Argument list array        */
  334.  
  335.     /* If this doesn't work, try again with no arguments */
  336.     
  337.         & 1) == 0 && 
  338.  
  339.         (smg$get_term_data(    /* Get terminal data        */
  340.             &termtype,    /* Terminal table address    */
  341.             &request_code,    /* Request code            */
  342.             &max_buffer_length,/* Maximum buffer length    */
  343.             &ret_length,    /* Return length        */
  344.             buffer)        /* Capability data buffer    */
  345.  
  346.     /* Return NULL pointer if capability is not available */
  347.     
  348.             & 1) == 0)
  349.                 return NULL;
  350.  
  351.     /* Check for empty result */
  352.     if (ret_length == 0)
  353.         return NULL;
  354.     
  355.     /* Save current position so we can return it to caller */
  356.  
  357.     result = buffer;
  358.  
  359.     /* NIL terminate the sequence for return */
  360.     
  361.     buffer[ret_length] = 0;
  362.  
  363.     /* Advance buffer */
  364.  
  365.     buffer += ret_length + 1;
  366.  
  367.     /* Return capability to user */
  368.     return result;
  369. }
  370.  
  371.  
  372. /** I/O information block definitions **/
  373. struct iosb {            /* I/O status block            */
  374.     short    i_cond;        /* Condition value            */
  375.     short    i_xfer;        /* Transfer count            */
  376.     long    i_info;        /* Device i